/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package propres;

/**
 *
 * @author david
 */
import java.io.Serializable;
import java.util.*;

public class dieta implements Serializable {
    private List<dia> tdias;
    private int calorias;
    private int precio;

    public dieta() {
//{pre:---}
//{post:nos creara una dieta nueva }
        tdias = new ArrayList();
        calorias = 0;
        precio = 0;
    }

    public boolean equals(Object arg) {
//{pre:nos pasan por elmento implicito una dieta no nula}
//{post:nos dice si una dieta que nos entra como parametro implicito es igual a arg }
        if ((arg != null) && (arg instanceof dieta)) {
            // Hacemos un moldeado del Object general a tipo java511
            dieta temp = (dieta) arg;
            // Se realiza la comparacion y se devuelve el resultado
            return (tdias.equals(temp.tdias));
        } else {
            System.out.println("tipos incompatibles dieta");
            return (false);
        }
    }

    public void anadir_dia(dia d) throws Exception {
        
  //{pre:nos pasan como elmento implicito una dieta no nula}
  //{post:nos añade el dia d en la dieta que nos pasan como parametro implicito }
        List plat = new ArrayList();
   //miramos si el dia tiene algun plato 
        if (d.lplatos_dia().size() == 0) {
            //si no tiene platos creamos un dia vacio en la fecha de d
            anadir_pcomida(d.fecha(), null, 0);
        } else {
            //si tiene platos los añadimos en la dieta en la fecha del dia d 
            for (int i = 0; i < 5; i++) {
                plat = new ArrayList();
                plat = d.lplatos_comida(i);
                Iterator it = plat.iterator();
                int n = 0;
                while (it.hasNext()) {
                    anadir_pcomida(d.fecha(), (plato) plat.get(n), i);
                    n++;
                    it.next();
                }
            }

        }
    }

    public void anadir_pcomida(Date d, plato p, int com) throws Exception
    {
         
  //{pre:nos pasan como elmento implicito una dieta no nula}
  //{post:nos añade el plato p en  la comida com y la fecha d en la dieta que nos pasan como parametro implicito }
        dia nuevo = new dia(d);
        int i = 0;
        boolean acaba = true;
        Date f;
        Iterator it = tdias.iterator();
//miramos que la dieta tenga algun dia
        if (!it.hasNext()) {
            if (p != null) {
            //si no lo tiene añadimos un dia nuevo con el unico plato
                nuevo.anadir_plato(p, com);
            }

            tdias.add(nuevo);
        } else {
            //en el caso de que tenga dias tendremos que encontrar el dia si lo hubiera
            //y añadir el plato o bien añadir un dia nuevo en la dieta y ubicarlo en su posicion 
            //segun la fecha
            while (it.hasNext() && acaba) {
                f = tdias.get(i).fecha();
                if (d.equals(f)) {
                    acaba = false;

                    nuevo = tdias.get(i);
                    if (p != null) {
                        nuevo.anadir_plato(p, com);
                    }
                    tdias.set(i, nuevo);
                } else {
                    if (d.before(f)) {
                        acaba = false;
                        nuevo = tdias.get(i);
                        nuevo = new dia(d);
                        if (p != null) {
                            nuevo.anadir_plato(p, com);
                        }
                        tdias.add(i, nuevo);
                        it = tdias.iterator();
                    }
                }

                it.next();
                i++;
            }
            if (acaba) {
                nuevo = new dia(d);
                if (p != null) {
                    nuevo.anadir_plato(p, com);
                }
                tdias.add(nuevo);
            }
        }
    }

    public boolean modificar_pcomida(Date d, plato p, int com) throws Exception {//comida <5
//{pre:nos pasan como elmento implicito una dieta no nula}
//{post:nos modifica el plato p en  la comida com y la fecha d en la dieta
        //que nos pasan como parametro implicito, en caso de no encontrarlo nos devuelve falso }
        int i = 0;
        boolean acaba = true;
        boolean encontrado = false;
        Iterator it = tdias.iterator();
        Date f;
        //en caso de que la dieta no este nula, buscamos el dia
        if (!tdias.isEmpty()) {
            while (it.hasNext() && acaba) {
                f = tdias.get(i).fecha();
                if (d.equals(f)) {
           ///si encontramos la fecha, debemos buscar el plato a modificar
                    dia nuevo = new dia(d);
                    nuevo = tdias.get(i);
                    acaba = false;
                    if (nuevo.modificar_plato(p, com)) {
                        tdias.set(i, nuevo);
                        encontrado = true;
                    }
                } else {
                    //si no lo encontramos salimos
                    if (d.before(f)) {
                        acaba = false;
                    }
                }
                it.next();
                i++;
            }
        }
        return encontrado;
    }

    public boolean eliminar_pcomida(Date d, plato p, int com) throws Exception {//comida <5
//{pre:nos pasan como elmento implicito una dieta no nula}
//{post:nos borra el plato p en  la comida com y la fecha d en la dieta que nos 
        //pasan como parametro implicito, en caso de no encontrar esta nos devuelve falso }
        int i = 0;
        boolean acaba = true;
        boolean encontrado = false;
        Iterator it = tdias.iterator();
        Date f;
        if (!tdias.isEmpty()) {
            while (it.hasNext() && acaba) {
                f = tdias.get(i).fecha();
                if (d.equals(f)) {
                    dia nuevo = new dia(d);
                    nuevo = tdias.get(i);
                    acaba = false;
                    if (nuevo.elim_plato(p, com)) {
                        if (nuevo.lplatos_dia().isEmpty()) {
                            tdias.remove(i);
                        } 
                        else {
                            tdias.set(i, nuevo);
                        }
                        encontrado = true;
                    }
                } else { 
                    if (d.before(f)) {
                        acaba = false;
                    }
                }
                it.next();
                i++;
            }
        }
        return encontrado;
    }

    public boolean eliminar_comida(Date d, int com) throws Exception {//comida <5
//{pre:nos pasan como elmento implicito una dieta no nula}
//{post:nos borra la comida com y de la fecha d en la dieta que nos 
        //pasan como parametro implicito, en caso de no encontrar esta nos devuelve falso }
        int i = 0;
        boolean acaba = true;
        boolean encontrado = false;
        Iterator it = tdias.iterator();
        Date f;
        if (!tdias.isEmpty()) {
            while (it.hasNext() && acaba) {
                f = tdias.get(i).fecha();
                if (d.equals(f)) {
                    dia nuevo = new dia(d);
                    nuevo = tdias.get(i);
                    acaba = false;
                    nuevo.borrar_comida(com);
                    if (nuevo.lplatos_dia().isEmpty()) {
                        tdias.remove(i);
                    } 
                    else {
                        tdias.set(i, nuevo);
                    }
                    encontrado = true;

                } else { 
                    if (d.before(f)) {
                        acaba = false;
                    }
                }
                it.next();
                i++;
            }
        }
        return encontrado;
    }

    public boolean eliminar_dia(Date d) throws Exception {//comida <5
//{pre:nos pasan como elmento implicito una dieta no nula}
//{post:nos borra el dia con fecha d en la dieta que nos pasan como 
//parametro implicito, en caso de no encontrar este nos devuelve falso }
        int i = 0;
        boolean acaba = true;
        boolean encontrado = false;
        Iterator it = tdias.iterator();
        Date f;
        if (!tdias.isEmpty()) {
            while (it.hasNext() && acaba) {
                f = tdias.get(i).fecha();
                if (d.equals(f)) {
                    acaba = false;
                    encontrado = d.equals(tdias.remove(i).fecha());
                } else { 
                    if (d.before(f)) {
                        acaba = false;
                    }
                }
                it.next();
                i++;
            }
        }
        return encontrado;
    }

    public List listar_cdias(Date d1, Date d2) throws Exception {//lista las comidas entre d1 y d2
//{pre:nos pasan como elmento implicito una dieta no nula}
//{post:devuelve una lista con todos los platos comprendido entre estos dos dias,
//incluidos estos dos}
        List list = new ArrayList();
        int i = 0;
        boolean acaba = true;
        Iterator it = tdias.iterator();
        Date f1;
        //entramos en caso de que tenga algun dia
        if (!tdias.isEmpty()) {
            while (it.hasNext() && acaba) {
                f1 = tdias.get(i).fecha();
                if (d1.equals(f1) || d2.equals(f1) || (d1.before(f1) && (d2.after(f1)))) {
                    list.addAll(tdias.get(i).lplatos_dia());
                } else { 
                    if (d2.before(f1)) {
                        ///cuando nos pasamos de la fecha d2, acaba
                        acaba = false;
                    }
                }
                it.next();
                i++;
            }
        }
        return list;

    }

    public List obtener_dias(Date d1, Date d2) throws Exception {
//{pre:nos pasan como elmento implicito una dieta no nula}
//{post:retorna una lista de dias comprendida entre d1 y d2 incluidos estos dos}
        List list = new ArrayList();
        int i = 0;
        boolean acaba = true;
        Iterator it = tdias.iterator();
        Date f1;
        if (!tdias.isEmpty()) {
            while (it.hasNext() && acaba) {
                f1 = tdias.get(i).fecha();
                if (d1.equals(f1) || d2.equals(f1) || (d2.after(f1) && (d1.before(f1)))) {
                    list.add(tdias.get(i));
                } else { ///si se pasa, acaba
                    if (d2.before(f1)) {
                        acaba = false;
                    }
                }
                it.next();
                i++;
            }
        }
        return list;


    }

    public List lista_platos(List<alimento> b, estrucalim Z) throws Exception {
//{pre:nos dan una estructura de alimentos y una lista de alimentos no nula}
//{post:retorna una lista de platos  generada con todos los alimentos de nuestra estructura}
        List p = new ArrayList();

        int t = 0;

        Iterator i = b.iterator();

        while (i.hasNext()) {
            if (b.get(t).Get_clasificacion().equals("principal")) {
                Iterator j = b.iterator();
                int r = 0;
                while (j.hasNext()) {
                    if (b.get(r).Get_clasificacion().equals("secundario")) {
                        String[] componentes = new String[2];
                        String q = new String(); 
                               q= b.get(t).Get_Nombre();
                        String w = new String();
                        w=b.get(r).Get_Nombre();
                        componentes[0] = q;
                        componentes[1] = w;
                        plato p1 = new plato(q + " con " + w, componentes, Z);
                        p.add(p1);
                    }
                    r++;
                    j.next();
                }
            }
            t++;
            i.next();
        }

        return p;

    }

    
    public arbol generar_dietauto(List<plato> plat, Date fecha_ini, preferencias pref, int numsol, List<int[]> tbit) throws Exception {
//{pre:la lista de platos, la fecha inicial, las preferencias, el nombre de soluciones y la lista de 
//bits representantes de el numero de comidas por comida no deven de ser nulos}
//{post:dada una lista de platos, una fecha inicial, unas preferencias, un numero de soluciones y 
//una tabla de bits representante de las comidas de cada dia, la función nos retorna un arbol de dietas
//ordenadas segun las preferencias, con platos no restringidos por esas preferencias. Este arbol tendrá
//una altura numsol  con un numero de comidas por dia que sigue la lista tbit y iniciadas a la fecha  
//fecha_ini}                     
        arbol arb = new arbol();
        arbol aux1 = new arbol();
        List<plato> plat1 = new ArrayList();
        int[] tbitp = tbit.get(0);
        int ntbit = 0;
        int n = 0;
//recorremos la lista tbits buscando dias que tengan la misma estructura de platos tbit
        while (ntbit < tbit.size()) {
            if (tbit.get(ntbit) != null) {
                tbitp = tbit.get(ntbit);
                Iterator it = tbit.iterator();
                n = 0;
                plat1.addAll(plat);
                int[] diasiguales = new int[tbit.size()];
                while (it.hasNext()) {
                    //las posiciones de la lista que tengan la misma tabla de bits las ponemos nulas
                    //y las agrupamos a todas en tbit
                    if (tbit.get(n) != null) {
                        if (t_igual(tbit.get(n), tbitp)) {
                            diasiguales[n] = 1;
                            tbit.set(n, null);
                        }
                    }
                    it.next();
                    n++;
                }
                //a continuacion generamos la dieta con el arbol que teniamos, y los
                //la tabla de bits de dias iguales
                aux1 = new arbol();
                aux1.copia_arbol(generar_dieta_r(plat, fecha_ini, pref, numsol, tbitp, diasiguales, arb), pref);
            }
            arb = new arbol();
            arb.copia_arbol(aux1, pref);
            ntbit++;
        }
        return arb;
    }

    public arbol generar_dieta1(List<dia> dias, Date fecha_ini, int d, preferencias pref, int numsol, int[] tbit) throws Exception {
//{pre:la lista de dias, la fecha inicial, los dias d de la dieta,las preferencias, el nombre de soluciones y la lista de 
//bits representantes de el numero de comidas por comida no deven de ser nulos}
//{post:dada una lista de dias, una fecha inicial,los dias d de la dieta, unas preferencias, un numero de soluciones y 
//una tabla de bits representante de las comidas del dia, la función nos retorna un arbol de dietas
//ordenadas segun las preferencias, con platos no restringidos por esas preferencias. Este arbol tendrá
//una altura numsol con un numero de comidas por dia que sigue la tabla tbit y iniciadas a la fecha  
//fecha_ini}
       
        Iterator it = dias.iterator();
        arbol arb = new arbol();
        int i = dias.size();
        int n = 0;
        if (i <= d) {
            dieta diet = new dieta();
            int j = 0;
            while (n < d) {
                Date o = new Date(fecha_ini.getYear(), fecha_ini.getMonth(), fecha_ini.getDate() + n);
                dia res = new dia();
                res = dias.get(j);
                res.Set_fecha(o);
                diet.anadir_dia(res);
                n++;
                j++;
                if (j == i) {
                    j = 0;
                }
            }
            diet.calcular_calprec();
            arb = new arbol(diet);
        } else {
            boolean b = true;
            while (it.hasNext() && n < dias.size() && b) {
                List<dia> l1 = new ArrayList();
                l1.addAll(dias);
                l1.remove(n);
                arb.copia_arbol(generar_dieta1(l1, fecha_ini, d, pref, numsol, tbit), pref);
                it.next();
                n++;
                if (arb.altura() > numsol) {
                    b = false;
                }
            }
        }
    
        return arb;
    }

    public arbol generar_dieta_r(List<plato> plat, Date fecha_ini, preferencias pref, int numsol, int[] tbit, int[] diasiguales, arbol arb) throws Exception {
//{pre:la lista de platos, la fecha inicial,las preferencias, el nombre de soluciones , la tabla de 
//bits representantes de el numero de comidas por comida,una tabla de dias iguales y un arbol de
//dietas no deven de ser nulos}
//{post:dada una lista de dias, una fecha inicial, unas preferencias, un numero de soluciones, una tabla de diasiguales y 
//una tabla de bits representante de las comidas del dia, la función nos retorna un arbol de dietas añadiendo los dias 
//marcados en la tabla diasiguales, ordenadas segun las preferencias y con platos no restringidos por esas preferencias. Este arbol tendrá
//una altura numsol con un numero de comidas por dia que sigue la tabla tbit y iniciadas a la fecha  
//fecha_ini}
        arbol aux = new arbol();
        List<dieta> ldiet = new ArrayList();
        int i = 0;
        ldiet = arb.recogeEnOrden2();
        if (ldiet.get(i) == null) {
            ldiet.clear();
        }
        Iterator ldi = ldiet.iterator();
        List<dia> de = new ArrayList();
        dieta diet = new dieta();
        de.addAll(diet.genera_diauto(plat, tbit, pref, numsol + 3));
        Iterator lde = de.iterator();
        while (ldi.hasNext() || (ldiet.isEmpty() && i < numsol)) {

            diet = new dieta();
            if (!ldiet.isEmpty()) {
                diet = ldiet.get(i);
            }
            dia di = new dia();
            lde = de.iterator();
            int n = 0;
            int j = 0;
            while (n < diasiguales.length && lde.hasNext()) {
                if (diasiguales[n] == 1) {
                    di = new dia();
                    Date o = new Date(fecha_ini.getYear(), fecha_ini.getMonth(), fecha_ini.getDate() + n);
                    di = de.get(j);
                    di.Set_fecha(o);
                    diet.anadir_dia(di);
                    j++;
                    lde.next();
                }
                n++;
            }
            aux.anadir_dieta(diet, pref);
            i++;

            if (!ldiet.isEmpty()) {
                ldi.next();
            }
            if (de.size() != 0) {
                di = new dia();
                di = de.get(0);
                de.remove(0);
                de.add(di);
            }

        }
        return aux;
    }

    public int comparar_dieta(dieta b, preferencias c) {
//{Pre:nos pasan dos arboles no nulos}
// {post:Dadas dos dietas a y b decidimos si la dieta a es mejor que la dieta b, es decir
// se ajusta más a las preferencias del cliente.}
        if (c != null) {
            int c1 = calorias - c.consultar_preferencias().Get_calorias().Get_C_total();
            int c2 = b.calorias - c.consultar_preferencias().Get_calorias().Get_C_total();
            int p1 = precio - c.consultar_preferencias().Get_precio().Get_P_total();
            int p2 = b.precio - c.consultar_preferencias().Get_precio().Get_P_total();

            if (c1 < 0) {
                c1 = c1 * (-1);
            }
            if (c2 < 0) {
                c2 = c2 * (-1);
            }
            if (p1 < 0) {
                p1 = p1 * (-1);
            }
            if (p2 < 0) {
                p2 = p2 * (-1);
            }
            c1 = c1 + p1;
            c2 = c2 + p2;

            return c1 - c2;
        } else {
            return 0;
        }

    }
    public List<dia> genera_diauto(List<plato> com, int[] tbit, preferencias pref, int numdias) throws Exception {
//{pre:la lista de platos,las preferencias, el nombre de soluciones y la tabla de enteros representantes de el numero de 
//comidas por comida no deven ser nulos}
//{post:dada una lista de platos, unas preferencias, un numero de soluciones, una tabla de diasiguales y 
//una tabla de enteros representante de las comidas del dia, la función nos retorna una lista de dias de tamaño numdias
// con los dias generados a partir  de la tabla de tbit y las preferencias}
        int d = 0;
        int i = 0;
        List<dia> list = new ArrayList();
        while (i < tbit.length) {
            d += tbit[i];
            i++;
        }
        if (d == 0) {
            while (d < numdias) {
                dia de = new dia();
                list.add(de);
                d++;
            }

        } else {
            int n = 0;
            List<plato> rest = new ArrayList();
            List<plato> c1 = new ArrayList();
            List<plato> c2 = new ArrayList();
            List<plato> c3 = new ArrayList();
            List<plato> c4 = new ArrayList();
            List<plato> c5 = new ArrayList();
            plato p = new plato();
            rest = p.platos_rest(com, pref);
            if(rest.isEmpty()){
                throw new Exception("No se encuentran platos de acorde con las preferencias");
                
            }
            Iterator it = rest.iterator();
         while (it.hasNext()) {

                if (rest.get(n).tip_com(0) && tbit[0] > 0) {
                    if(c1.size()==0){c1.add(rest.get(n));}
                    else{
                    c1.add(c1.size()%3,rest.get(n));}
                }
                if (rest.get(n).tip_com(1) && tbit[1] > 0) {
                    c2.add(0,rest.get(n));
                    //c2.add(rest.get(n));
                }
                if (rest.get(n).tip_com(2) && tbit[2] > 0) {
                    c3.add(c3.size()/2,rest.get(n));
                    //c3.add(rest.get(n));
                }
                if (rest.get(n).tip_com(3) && tbit[3] > 0) {
                    c4.add(c4.size()/3,rest.get(n));
                    //c4.add(rest.get(n));
                }
                if (rest.get(n).tip_com(4) && tbit[4] > 0) {
                    if((c5.size()%2)==0|| c5.size()==0){c5.add(0,rest.get(n));}
                    else{c5.add(1,rest.get(n));}
                    
                    //c5.add(rest.get(n));
                }
                it.next();
                n++;

            }
            i = c1.size() + c2.size() + c3.size() + c4.size() + c5.size();
            dia de = new dia();
            if (i <= d) {
                if (d == 0) {
                    list.add(de);
                } else {
                    n = 0;
                    if (tbit[0] == c1.size() && tbit[1] == c2.size() && tbit[2] == c3.size() && tbit[3] == c4.size() && tbit[4] == c5.size()) {   
                        de.anadir_comida(c1, 0);
                        de.anadir_comida(c2, 1);
                        de.anadir_comida(c3, 2);
                        de.anadir_comida(c4, 3);
                        de.anadir_comida(c5, 4);
                    } else {
                        i = 0;
                        it = com.iterator();
                        while (i < 5 && it.hasNext()) {
                            n = 0;
                            d = 0;
                            while (d < tbit[i]) {
                                if (com.get(n).tip_com(i)) {
                                    p = new plato();
                                    p = com.get(n);
                                    de.anadir_plato(p, i);
                                    d++;
                                }
                                n++;
                                it.next();
                                if (!it.hasNext()) {
                                    it = com.iterator();
                                    n = 0;
                                }
                            }
                            i++;
                        }

                    }
                    list.add(de);
                }

            } else {
                System.out.println("c1 tam:"+c1.size()+"  lo otro "+tbit[0]*numdias);
                System.out.println("c2 tam:"+c2.size()+"  lo otro "+tbit[1]*numdias);
                System.out.println("c3 tam:"+c3.size()+"  lo otro "+tbit[2]*numdias);
                System.out.println("c4 tam:"+c4.size()+"  lo otro "+tbit[3]*numdias);
                System.out.println("c5 tam:"+c5.size()+"  lo otro "+tbit[4]*numdias);
                boolean bo1=false;if(tbit[0]*numdias<c1.size()){bo1=true;}
                boolean bo2=false;if(tbit[1]*numdias<c2.size()){bo2=true;}
                boolean bo3=false;if(tbit[2]*numdias<c3.size()){bo3=true;}
                boolean bo4=false;if(tbit[3]*numdias<c4.size()){bo4=true;}
                boolean bo5=false;if(tbit[4]*numdias<c5.size()){bo5=true;}
                list.addAll(genera_dia_r(c1, c2, c3, c4, c5, pref, tbit, numdias,bo1,bo2,bo3,bo4,bo5));
            }
        }
        return list;
    }
     List<dia> genera_dia_r(List<plato> c1, List<plato> c2, List<plato> c3, List<plato> c4, List<plato> c5, preferencias pref, int[] tbit, int numdias, boolean bo1,boolean bo2,boolean bo3,boolean bo4,boolean bo5 ) throws Exception {
//{pre:las listas de platos,las preferencias, el nombre de soluciones y la tabla de enteros representantes de el numero de 
//comidas por comida no deven ser nulos}
//{post:dada las listas de platos, unas preferencias, un numero de soluciones, una tabla de diasiguales y 
//una tabla de enteros representante de las comidas del dia, la función nos retorna una lista de dias de tamaño numdias
// con los dias generados a partir  de la tabla de tbit y las preferencias. Estos dias estaran formados por los platos
// que contienen las listas de platos que corresponden a cada comida}      
        List<dia> list = new ArrayList();
        int d = 0;
        int i = 0;
        while (i < tbit.length) {
            d += tbit[i];
            i++;
        }
        i = c1.size() + c2.size() + c3.size() + c4.size() + c5.size();
        dia de = new dia();
        if (i <= d) {
            if (tbit[0] == c1.size() && tbit[1] == c2.size() && tbit[2] == c3.size() && tbit[3] == c4.size() && tbit[4] == c5.size()) { 
                de.anadir_comida(c1, 0);if(bo1){c1.clear();}
                de.anadir_comida(c2, 1);if(bo2){c2.clear();}
                de.anadir_comida(c3, 2);if(bo3){c3.clear();}
                de.anadir_comida(c4, 3);if(bo4){c4.clear();}
                de.anadir_comida(c5, 4);if(bo5){c5.clear();}                          
                list.add(de);
          }      
        } else {
            boolean b = true;
            List aux1 = new ArrayList();
            List aux2 = new ArrayList();
            List aux3 = new ArrayList();
            List aux4 = new ArrayList();
            List aux5 = new ArrayList();
            plato p = new plato();
            plato p1 = new plato();
            plato p2 = new plato();
            plato p3 = new plato();
            plato p4 = new plato();
            plato p5 = new plato();
            if( (c1.isEmpty() && tbit[0] != 0) || (c2.isEmpty() && tbit[1] != 0) || (c3.isEmpty() && tbit[2] != 0) || (c4.isEmpty() && tbit[3] != 0) || (c5.isEmpty() && tbit[4] != 0)){
                if(c1.isEmpty() && tbit[0] != 0){
            System.out.println(" no existen suficientes recurso para com 1");
            throw new Exception("no existen suficientes recurso para com 1");} 
             if(c2.isEmpty() && tbit[1] != 0){
            System.out.println(" no existen suficientes recurso para com 2");
            throw new Exception("no existen suficientes recurso para com 2");}
             if(c3.isEmpty() && tbit[2] != 0){
            System.out.println(" no existen suficientes recurso para com 3");
            throw new Exception("no existen suficientes recurso para com 3");}
             if(c4.isEmpty() && tbit[3] != 0){
            System.out.println(" no existen suficientes recurso para com 4");
            throw new Exception("no existen suficientes recurso para com 4");}
             if(c5.isEmpty() && tbit[4] != 0){
            System.out.println(" no existen suficientes recurso para com 5");
            throw new Exception("no existen suficientes recurso para com 5");}
            }
            while (numdias > list.size() && !(c1.size() + aux1.size() == tbit[0] && c2.size() + aux2.size() == tbit[1] && c3.size() + aux3.size() == tbit[2] && c4.size() + aux4.size() == tbit[3] && c5.size() + aux5.size() == tbit[4]) && b && !((c1.isEmpty() && tbit[0] != 0) || (c2.isEmpty() && tbit[1] != 0) || (c3.isEmpty() && tbit[2] != 0) || (c4.isEmpty() && tbit[3] != 0) || (c5.isEmpty() && tbit[4] != 0))) {
                boolean b1 = false;
                boolean b2 = false;
                boolean b3 = false;
                boolean b4 = false;
                boolean b5 = false;
                if (tbit[0] == 0) {
                    c1.clear();
                }
                if (tbit[1] == 0) {
                    c2.clear();
                }
                if (tbit[2] == 0) {
                    c3.clear();
                }
                if (tbit[3] == 0) {
                    c4.clear();
                }
                if (tbit[4] == 0) {
                    c5.clear();
                }
                if (tbit[0] < c1.size() + aux1.size() && !c1.isEmpty() && tbit[0] != 0) {
      
                    p1 = p.platos_min(c1, pref);
                    b1 = true;
                    c1.remove(p1);
                    
                } else {
                    if (tbit[0] > c1.size() + aux1.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 1");
                         throw new Exception("no existen suficientes recurso para com 1");
                    }
                }
                if (tbit[1] < c2.size() + aux2.size() && !c2.isEmpty() && tbit[1] != 0) {
                    p2 = p.platos_min(c2, pref);
                    b2 = true;
                    c2.remove(p2);
                } else {
                    if (tbit[1] > c2.size() + aux2.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 2");
                        throw new Exception("no existen suficientes recurso para com 2");
                    }    
                }
                if (tbit[2] < c3.size() + aux3.size() && !c3.isEmpty() && tbit[2] != 0) {
                    p3 = p.platos_min(c3, pref);
                    b3 = true;
                    c3.remove(p3);
                } else {
                    if (tbit[2] > c3.size() + aux3.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 3");
                        throw new Exception("no existen suficientes recurso para com 3");
                    }
                }
                if (tbit[3] < c4.size() + aux4.size() && !c4.isEmpty() && tbit[3] != 0) {
                    p4 = p.platos_min(c4, pref);
                    b4 = true;
                    c4.remove(p4);
                } else {
                    if (tbit[3] > c4.size() + aux4.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 4");
                        throw new Exception("no existen suficientes recurso para com 4");
                    }
                }
                if (tbit[4] < c5.size() + aux5.size() && !c5.isEmpty() && tbit[4] != 0) {
                    p5 = p.platos_min(c5, pref);
                    b5 = true;
                    c5.remove(p5);
                } else {
                    if (tbit[4] > c5.size() + aux5.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 5");
                        throw new Exception("no existen suficientes recurso para com 5");
                    }
                }
                if (b) {
                    c1.addAll(aux1);
                    c2.addAll(aux2);
                    c3.addAll(aux3);
                    c4.addAll(aux4);
                    c5.addAll(aux5);

                    List<dia> list1 = new ArrayList();
                    list1.addAll(genera_dia_r(c1, c2, c3, c4, c5, pref, tbit, numdias,bo1,bo2,bo3,bo4,bo5));
                    Iterator eot = list1.iterator();
                    int n1 = 0;
                    
                    while (eot.hasNext()) {
                        if (!list.contains(list1.get(n1))) {
                            list.add(list1.get(n1));
                        }
                        n1++;
                        eot.next();
                    }
                    
                    c1.removeAll(aux1);
                    c2.removeAll(aux2);
                    c3.removeAll(aux3);
                    c4.removeAll(aux4);
                    c5.removeAll(aux5);
                    if (b1) {
                        aux1.add(p1);
                    }
                    if (b2) {
                        aux2.add(p2);
                    }
                    if (b3) {
                        aux3.add(p3);
                    }
                    if (b4) {
                        aux4.add(p4);
                    }
                    if (b5) {
                        aux5.add(p5);
                    }
                if((c1.size()+aux1.size()==tbit[0]&&bo1)||(c2.size()+aux2.size()==tbit[1]&&bo2)||(c3.size()+aux3.size()==tbit[2]&&bo3)||(c4.size()+aux4.size()==tbit[3]&&bo4)||(c5.size()+aux5.size()==tbit[4]&&bo5)){
                   b=false;
                }
                }
            }
            
            
            c1.addAll(aux1);
            c2.addAll(aux2);
            c3.addAll(aux3);
            c4.addAll(aux4);
            c5.addAll(aux5);
        }

        return list;
    }
    
   /* List<dia> genera_dia_r(List<plato> c1, List<plato> c2, List<plato> c3, List<plato> c4, List<plato> c5, preferencias pref, int[] tbit, int numdias, boolean bo1,boolean bo2,boolean bo3,boolean bo4,boolean bo5 ) throws Exception {
//{pre:las listas de platos,las preferencias, el nombre de soluciones y la tabla de enteros representantes de el numero de 
//comidas por comida no deven ser nulos}
//{post:dada las listas de platos, unas preferencias, un numero de soluciones, una tabla de diasiguales y 
//una tabla de enteros representante de las comidas del dia, la función nos retorna una lista de dias de tamaño numdias
// con los dias generados a partir  de la tabla de tbit y las preferencias. Estos dias estaran formados por los platos
// que contienen las listas de platos que corresponden a cada comida}      
        List<dia> list = new ArrayList();
        int d = 0;
        int i = 0;
        while (i < tbit.length) {
            d += tbit[i];
            i++;
        }
        i = c1.size() + c2.size() + c3.size() + c4.size() + c5.size();
        dia de = new dia();
        if (i <= d) {
            if (tbit[0] == c1.size() && tbit[1] == c2.size() && tbit[2] == c3.size() && tbit[3] == c4.size() && tbit[4] == c5.size()) { 
                de.anadir_comida(c1, 0);if(bo1){c1.clear();}
                de.anadir_comida(c2, 1);if(bo2){c2.clear();}
                de.anadir_comida(c3, 2);if(bo3){c3.clear();}
                de.anadir_comida(c4, 3);if(bo4){c4.clear();}
                de.anadir_comida(c5, 4);if(bo5){c5.clear();}                          
                list.add(de);
          }      
        } else {
            boolean b = true;
            List aux1 = new ArrayList();
            List aux2 = new ArrayList();
            List aux3 = new ArrayList();
            List aux4 = new ArrayList();
            List aux5 = new ArrayList();
            plato p = new plato();
            plato p1 = new plato();
            plato p2 = new plato();
            plato p3 = new plato();
            plato p4 = new plato();
            plato p5 = new plato();
            if( (c1.isEmpty() && tbit[0] != 0) || (c2.isEmpty() && tbit[1] != 0) || (c3.isEmpty() && tbit[2] != 0) || (c4.isEmpty() && tbit[3] != 0) || (c5.isEmpty() && tbit[4] != 0)){
                if(c1.isEmpty() && tbit[0] != 0){
            System.out.println(" no existen suficientes recurso para com 1");
            throw new Exception("no existen suficientes recurso para com 1");} 
             if(c2.isEmpty() && tbit[1] != 0){
            System.out.println(" no existen suficientes recurso para com 2");
            throw new Exception("no existen suficientes recurso para com 2");}
             if(c3.isEmpty() && tbit[2] != 0){
            System.out.println(" no existen suficientes recurso para com 3");
            throw new Exception("no existen suficientes recurso para com 3");}
             if(c4.isEmpty() && tbit[3] != 0){
            System.out.println(" no existen suficientes recurso para com 4");
            throw new Exception("no existen suficientes recurso para com 4");}
             if(c5.isEmpty() && tbit[4] != 0){
            System.out.println(" no existen suficientes recurso para com 5");
            throw new Exception("no existen suficientes recurso para com 5");}
            }
            while (numdias > list.size() && !(c1.size() + aux1.size() == tbit[0] && c2.size() + aux2.size() == tbit[1] && c3.size() + aux3.size() == tbit[2] && c4.size() + aux4.size() == tbit[3] && c5.size() + aux5.size() == tbit[4]) && b && !((c1.isEmpty() && tbit[0] != 0) || (c2.isEmpty() && tbit[1] != 0) || (c3.isEmpty() && tbit[2] != 0) || (c4.isEmpty() && tbit[3] != 0) || (c5.isEmpty() && tbit[4] != 0))) {
                boolean b1 = false;
                boolean b2 = false;
                boolean b3 = false;
                boolean b4 = false;
                boolean b5 = false;
                if (tbit[0] == 0) {
                    c1.clear();
                }
                if (tbit[1] == 0) {
                    c2.clear();
                }
                if (tbit[2] == 0) {
                    c3.clear();
                }
                if (tbit[3] == 0) {
                    c4.clear();
                }
                if (tbit[4] == 0) {
                    c5.clear();
                }
                if (tbit[0] < c1.size() + aux1.size() && !c1.isEmpty() && tbit[0] != 0) {
      
                    p1 = p.platos_min(c1, pref);
                    b1 = true;
                    c1.remove(p1);
                    
                } else {
                    if (tbit[0] > c1.size() + aux1.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 1");
                         throw new Exception("no existen suficientes recurso para com 1");
                    }
                }
                if (tbit[1] < c2.size() + aux2.size() && !c2.isEmpty() && tbit[1] != 0) {
                    p2 = p.platos_min(c2, pref);
                    b2 = true;
                    c2.remove(p2);
                } else {
                    if (tbit[1] > c2.size() + aux2.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 2");
                        throw new Exception("no existen suficientes recurso para com 2");
                    }    
                }
                if (tbit[2] < c3.size() + aux3.size() && !c3.isEmpty() && tbit[2] != 0) {
                    p3 = p.platos_min(c3, pref);
                    b3 = true;
                    c3.remove(p3);
                } else {
                    if (tbit[2] > c3.size() + aux3.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 3");
                        throw new Exception("no existen suficientes recurso para com 3");
                    }
                }
                if (tbit[3] < c4.size() + aux4.size() && !c4.isEmpty() && tbit[3] != 0) {
                    p4 = p.platos_min(c4, pref);
                    b4 = true;
                    c4.remove(p4);
                } else {
                    if (tbit[3] > c4.size() + aux4.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 4");
                        throw new Exception("no existen suficientes recurso para com 4");
                    }
                }
                if (tbit[4] < c5.size() + aux5.size() && !c5.isEmpty() && tbit[4] != 0) {
                    p5 = p.platos_min(c5, pref);
                    b5 = true;
                    c5.remove(p5);
                } else {
                    if (tbit[4] > c5.size() + aux5.size()) {
                        b = false;
                        System.out.println(" no existen suficientes recurso para com 5");
                        throw new Exception("no existen suficientes recurso para com 5");
                    }
                }
                if (b) {
                    c1.addAll(aux1);
                    c2.addAll(aux2);
                    c3.addAll(aux3);
                    c4.addAll(aux4);
                    c5.addAll(aux5);

                    List<dia> list1 = new ArrayList();
                    list1.addAll(genera_dia_r(c1, c2, c3, c4, c5, pref, tbit, numdias,bo1,bo2,bo3,bo4,bo5));
                    Iterator eot = list1.iterator();
                    int n1 = 0;
                    
                    while (eot.hasNext()) {
                        if (!list.contains(list1.get(n1))) {
                            list.add(list1.get(n1));
                        }
                        n1++;
                        eot.next();
                    }
                    
                    c1.removeAll(aux1);
                    c2.removeAll(aux2);
                    c3.removeAll(aux3);
                    c4.removeAll(aux4);
                    c5.removeAll(aux5);
                    if (b1) {
                        aux1.add(p1);
                    }
                    if (b2) {
                        aux2.add(p2);
                    }
                    if (b3) {
                        aux3.add(p3);
                    }
                    if (b4) {
                        aux4.add(p4);
                    }
                    if (b5) {
                        aux5.add(p5);
                    }
                }
            }
            
            
                c1.addAll(aux1);
            c2.addAll(aux2);
            c3.addAll(aux3);
            c4.addAll(aux4);
            c5.addAll(aux5);
        }

        return list;
    }*/
 public void  intercala_dieta(dieta d) throws Exception {
     List<dia> l1 = new ArrayList();
     l1.addAll(d.consultar_dias());
     Iterator it=l1.iterator();
     int n=0;
     while(it.hasNext()){
         anadir_dia(l1.get(n));
         it.next();
         n++;
     }
     
 }
    
    public void calcular_calprec() throws Exception {

        calorias = 0;
        precio = 0;
        List<dia> list = new ArrayList();
        list = consultar_dias();
        Iterator it = list.iterator();
        int n = 0;
        int i = 0;
        while (it.hasNext()) {
            List<plato> l1 = new ArrayList();
            l1 = list.get(n).lplatos_dia();
            Iterator et = l1.iterator();
            i = 0;
            while (et.hasNext()) {
                calorias += l1.get(i).Get_Calorias();
                if(!l1.get(i).Get_pagado()){
                precio += l1.get(i).Get_Precio();
                }
                et.next();
                i++;
            }

            n++;
            it.next();
        }


    }

    public List<dia> consultar_dias() throws Exception {
        return tdias;
    }

    public int consultar_precio() throws Exception {

        return precio;
    }

    public int consultar_calorias() throws Exception {

        return calorias;
    }

    int ntbit(int[] tbit) throws Exception {
        int n = tbit[0] + tbit[1] + tbit[2] + tbit[3] + tbit[4];
        return n;

    }

    boolean t_igual(int[] t1, int[] t2) throws Exception {
        boolean b = true;
        if (t1[0] != t2[0]) {
            b = false;
        }
        if (t1[1] != t2[1]) {
            b = false;
        }
        if (t1[2] != t2[2]) {
            b = false;
        }
        if (t1[3] != t2[3]) {
            b = false;
        }
        if (t1[4] != t2[4]) {
            b = false;
        }
        return b;
    }
}



